﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using TmU220PrintHelperV2d0.Entity;
using TmU220PrintHelperV2d0.Interface;
using TmU220PrintHelperV2d0.Service;
using ZhangLogSysV1d0;

namespace TmU220PrintHelperV2d0
{
    /// <summary>
    /// TmU220打印机
    /// </summary>
    public class TmU220PrinterV2d0:IPrinter
    {
        /// <summary>
        /// 打印機Tcp客戶端連接套接字
        /// </summary>
        public TcpClient PrinterTcpClient { get; set; }
        /// <summary>
        /// 打印機常駐漢字字符類別
        /// </summary>
        public string PrinterResidentChineseEncodingName { get; set; }
        /// <summary>
        /// 紙寬
        /// </summary>
        public int PaperWidth { get; set; }
        /// <summary>
        /// 字符間隔
        /// </summary>
        public int DotSpaceBetweenCharacter { get; set; }
        /// <summary>
        /// 每行的字符個數
        /// </summary>
        public int CharactersPerLine { get; set; }
        public string DeviceType { get; set; }
        public TmU220PrinterV2d0()
        {
            PrinterTcpClient = null;
            PrinterResidentChineseEncodingName = "Big5";
            PaperWidth = 76;
            DotSpaceBetweenCharacter = 3;
            CharactersPerLine = 40;
            PrinterTcpClient = new TcpClient();
            DeviceType = "TM-U220";
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="tcpClient">连接打印机的套接字</param>
        /// <param name="chineseEncodingName">中文编码名称，</param>
        public TmU220PrinterV2d0(TcpClient tcpClient,string chineseEncodingName)
        {
            PrinterTcpClient = null;
            PrinterResidentChineseEncodingName = chineseEncodingName;
            PaperWidth = 76;
            DotSpaceBetweenCharacter = 3;
            CharactersPerLine = 40;
            PrinterTcpClient = tcpClient;
            DeviceType = "TM-U220";
        }

        private void DisConnnect()
        {
            if (PrinterTcpClient != null)
                PrinterTcpClient.Close();
        }
        /// <summary>
        /// 发送字节数组到打印机
        /// </summary>
        /// <param name="bytes">字节指令</param>
        /// <returns></returns>
        public  bool SendBytes(byte[] bytes)
        {
             return SendBytesToPrinter(bytes,PrinterTcpClient);
        }
        /// <summary>
        /// 发送字节数组到打印机，通过tcpClient
        /// </summary>
        /// <param name="bytes">待发送字节数组</param>
        /// <param name="printerTcpClient">连接打印机的套接字</param>
        /// <returns></returns>
        public static bool SendBytesToPrinter(byte[] bytes,TcpClient printerTcpClient)
        {
            bool isSuccess = false;
            try
            {
                if (printerTcpClient != null && printerTcpClient.Connected)
                {
                    NetworkStream netStream = printerTcpClient.GetStream();
                    netStream.Write(bytes, 0, bytes.Length);
                    netStream.Flush();
                    isSuccess = true;
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
                isSuccess = false;
            }
            return isSuccess;
        }


        /// <summary>
        /// 发送字符串打打印机,根据该打印机的汉字编码，将Unicode编码转换为打印机的汉字编码
        /// </summary>
        /// <param name="content">待打印字符串</param>
        /// <returns></returns>
        public bool SendStringToPrinter(string content)
        {
            return SendTextToPrinter(content, PrinterTcpClient, PrinterResidentChineseEncodingName);
        }
        /// <summary>
        /// 发送字符串打打印机
        /// </summary>
        /// <param name="text">待打印文本</param>
        /// <param name="encodingName">待打印机字符串的编码名称</param>
        /// <returns></returns>
        public static bool SendTextToPrinter(string text, TcpClient printerTcpClient, string encodingName = "Big5")
        {
            bool isSuccess = false;
            try
            {
                //将文本编码转换为打印机字库编码的字节数组
                Encoding printerEncoding = Encoding.GetEncoding(encodingName);
                byte[] printBytes = printerEncoding.GetBytes(text);
                isSuccess = SendBytesToPrinter(printBytes, printerTcpClient);
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }

        /// <summary>
        /// 打印位图
        /// </summary>
        /// <param name="bitmap">400像素宽，高度为8的整倍数</param>
        /// <returns></returns>
        public bool SendBitmap(Bitmap bitmap)
        {
            bool result = false;
            try
            {
                bool isCorrect = CheckBitmapFormat(bitmap);
                if (isCorrect == false) return false;
                else
                {
                    int bitmapHeight = bitmap.Height;
                    int rowCount = bitmapHeight / 8;//行高度8个像素
                    for (int i = 0; i < rowCount; i++)
                    {
                        //将行位图（高度8个像素）发送到打印机
                        SendScanLineOfBitmap(i, bitmap);
                        //15个打印机垂直运动单位
                        byte TMU220B_VerticalMoveUnits = 15;
                        //打印机走纸15个垂直运动单位
                        SendBytes(PrinterEscCommandConstantV2d0.printAndFeedPaper_VerticalUnit(TMU220B_VerticalMoveUnits));
                    }
                    return true;
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return result;

        }

        /// <summary>
        /// 发送位图的扫描行（对于TM-U220，一个扫描行8个像素高，400个像素宽）
        /// </summary>
        /// <param name="scanLineIndex">扫描行序号</param>
        /// <param name="bitmap">待发送 位图</param>
        private void SendScanLineOfBitmap(int scanLineIndex, Bitmap bitmap)
        {
            bool isCorrect = CheckBitmapFormat(bitmap);
            try
            {
                if (isCorrect)
                {
                    //将位图指定行转换成,打印机的位图字节数组,双密度打印
                    byte[] bitmapByteArray = PrinterUtilityV2d0.pic2PxPoint8NeedleDoubleDensity(bitmap, scanLineIndex);
                    if (PrinterTcpClient != null && PrinterTcpClient.Connected)
                    {
                        NetworkStream netStream = PrinterTcpClient.GetStream();
                        netStream.Write(bitmapByteArray, 0, bitmapByteArray.Length);
                        netStream.Flush();
                    }
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
        }

        /// <summary>
        /// 发送打印任务项到打印机
        /// </summary>
        /// <param name="taskItem">打印任务项</param>
        /// <returns></returns>
        public bool SendPrintTaskItemToPrinter(PrintTaskItemV2d0 taskItem)
        {
            bool isSuccess = false;
            try
            {
                if (taskItem.FormatOfContent.PrintMode == "Text")
                {
                    isSuccess = SendPrintTaskItemUsingTextMode(taskItem);
                }
                else if (taskItem.FormatOfContent.PrintMode == "Image")
                {
                    isSuccess = SendPrintTaskItemUsingImageMode(taskItem);
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }
        /// <summary>
        /// 使用文本模式发送打印任务项
        /// 对于文本模式，只支持有限的几个格式，倍宽，倍高，粗体，下划线，左右对齐
        /// </summary>
        /// <param name="taskItem">打印任务项</param>
        /// <returns></returns>
        private bool SendPrintTaskItemUsingTextMode(PrintTaskItemV2d0 taskItem)
        {
            bool isSuccess = false;
            try
            {
                if (taskItem.Content.Length == 0) return false;
                //asc 字符串打印模式 支持倍宽，倍高，粗体，下划线
                byte AscPrintMode = GetAscPrintMode(taskItem);
                SendBytes(PrinterEscCommandConstantV2d0.AscFontPrintMode(AscPrintMode));
                //多字节字符打印模式 支持倍宽，倍高
                byte MbcsPrintMode = GetMbcsPrintMode(taskItem);
                SendBytes(PrinterEscCommandConstantV2d0.MbcsFontPrintMode(MbcsPrintMode));
                //对齐方式
                SetAlignOfPrinter(taskItem);
                //字体颜色
                SendFontColorCommand(taskItem);
                //开始打印
                SendStringToPrinter(taskItem.Content);
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }
        /// <summary>
        /// 得到asc字符的打印模式配置字节,设置倍宽,倍高,粗体，下划线,
        /// </summary>
        /// <returns></returns>
        private static byte GetAscPrintMode(PrintTaskItemV2d0 taskItem)
        {
            byte ascPrintMode = 0;
            //倍高
            if (taskItem.FormatOfContent.IsDoubleHeight)
            {
                //asc
                ascPrintMode = (byte)(ascPrintMode + 16);
            }
            //倍宽
            if (taskItem.FormatOfContent.IsDoubleWidth)
            {
                //asc
                ascPrintMode = (byte)(ascPrintMode + 32);
            }
            //asc粗体
            if (taskItem.FormatOfContent.IsBold)
            {
                ascPrintMode = (byte)(ascPrintMode + 8);
            }
            //asc下划线
            if (taskItem.FormatOfContent.IsUnderLine)
            {
                ascPrintMode = (byte)(ascPrintMode + 128);
            }
            return ascPrintMode;
        }
        /// <summary>
        /// 得到多字节字符的打印模式配置字节 设置倍宽,倍高,多字节字符的打印不支持粗体
        /// </summary>
        /// <returns></returns>
        private static byte GetMbcsPrintMode(PrintTaskItemV2d0 taskItem)
        {
            byte mbcsPrintMode = 0;
            //倍高
            if (taskItem.FormatOfContent.IsDoubleHeight)
            {
                //多字节字符
                mbcsPrintMode = (byte)(mbcsPrintMode + 8);
            }
            //倍宽
            if (taskItem.FormatOfContent.IsDoubleWidth)
            {
                //多字节字符
                mbcsPrintMode = (byte)(mbcsPrintMode + 4);
            }
            return mbcsPrintMode;
        }
        /// <summary>
        /// 设置打印机的文本打印对齐方式
        /// </summary>
        /// <param name="align">对齐方式</param>
        /// <returns></returns>
        private bool SetAlignOfPrinter(PrintTaskItemV2d0 taskItem)
        {
            bool result = false;
            try
            {
                if (taskItem.FormatOfContent.Align == "Left")
                {
                    SendBytes(PrinterEscCommandConstantV2d0.alignLeft());
                }
                else if (taskItem.FormatOfContent.Align == "Center")
                {
                    SendBytes(PrinterEscCommandConstantV2d0.alignCenter());
                }
                else if (taskItem.FormatOfContent.Align == "Right")
                {
                    SendBytes(PrinterEscCommandConstantV2d0.alignRight());
                }
                result = true;
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return result;
        }

        /// <summary>
        /// 发送自定义颜色指令
        /// </summary>
        /// <param name="taskItem">打印任务项，包含字体颜色字段</param>
        /// <returns></returns>
        private bool SendFontColorCommand(PrintTaskItemV2d0 taskItem)
        {
            bool result = false;
            try
            {
                byte[] commandByte=PrinterEscCommandConstantV2d0.fontColor(taskItem.FormatOfContent.FontColor);
                SendBytes(commandByte);
                result = true;
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
                result = false;
            }
            return result;
        }
        /// <summary>
        /// 使用图像模式发送打印任务项
        /// </summary>
        /// <param name="taskItem">打印任务项</param>
        /// <returns></returns>
        private bool SendPrintTaskItemUsingImageMode(PrintTaskItemV2d0 taskItem)
        {
            bool isSuccess = false;
            try
            {
                //发送字体颜色指令
                SendFontColorCommand(taskItem);
                //发送打印位图指令
                isSuccess = SendBitmap(taskItem.BitmapOfContent);
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }

        /// <summary>
        /// 对位图格式进行检查，宽度必须400像素，高度必须是8的整数倍
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static bool CheckBitmapFormat(Bitmap bitmap)
        {
            bool result = false;
            try
            {
                if (bitmap != null)
                {
                    int width = bitmap.Width;
                    int height = bitmap.Height;
                    if (width != 400) result = false;
                    else result = true;
                    if (height % 8 != 0) result = false;
                    else result = true;
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return result;
        }

    }
}
